package com.atguigu.tingshu.search.listener;

import com.atguigu.tingshu.search.service.impl.ItemServiceImpl;
import org.redisson.api.RBloomFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;

import java.time.Duration;
import java.util.List;

/**
 * 利用 SpringApplicationRunListener 监听项目启动，项目启动时，自动创建布隆过滤器
 * 这里必须使用Spring的扫描机制 不能使用@Component注解 在META-INF/spring.factories
 */
public class BloomFilterListener implements SpringApplicationRunListener {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 该方法是SpringBoot启动过程中(包含Spring容器中应用定义的Bean对象都创建完毕了)中回调
     * 这个started方法在启动过程中，会被调用两次，
     * 第一次是springcloud的组件调用的（此时Spring容器中没有应用中定义好的bean对象的），
     * 第二次是springboot的组件调用的（应用的bean对象都创建完毕了）
     *
     * @param context   the application context.
     * @param timeTaken the time taken to start the application or {@code null} if unknown
     */
    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        // todo 分布式布隆的数据同步
        boolean b = context.containsBean("bloomFilter");
        if (b) {
            RBloomFilter bloomFilter = context.getBean("bloomFilter", RBloomFilter.class);
            // 拿到过滤器后 未初始化数据 才进行初始化
            if (bloomFilter.count() == 0) {
                ItemServiceImpl itemServiceImpl = context.getBean("itemServiceImpl", ItemServiceImpl.class);
                List<Long> allAlbumId = itemServiceImpl.findAllAlbumId();
                allAlbumId.forEach(bloomFilter::add);
                logger.info("布隆过滤器中元素添加完毕，个数{}", bloomFilter.count());
            }
        }
    }
}
